package cn.chinaunicom.mini.program.dingtalk.openapi.service;

import com.alibaba.fastjson2.JSON;
import org.springframework.stereotype.Component;

import com.dingtalk.api.request.OapiUserListidRequest;
import com.dingtalk.api.request.OapiV2UserGetRequest;
import com.dingtalk.api.request.OapiV2UserGetuserinfoRequest;
import com.dingtalk.api.request.OapiV2UserListRequest;
import com.dingtalk.api.response.OapiUserListidResponse;
import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.dingtalk.api.response.OapiV2UserGetuserinfoResponse;
import com.dingtalk.api.response.OapiV2UserListResponse;
import com.taobao.api.ApiException;

import cn.chinaunicom.mini.program.dingtalk.constants.OpenApiUrls;
import cn.chinaunicom.mini.program.dingtalk.openapi.client.IDingTalkClient;
import lombok.extern.slf4j.Slf4j;

/**
 * @ProjectName: dingtalk-property
 * @Package: cn.chinaunicom.mini.program.dingtalk.openapi.service
 * @ClassName: UserService
 * @Description: 钉钉用户接口
 * @Author: wangjc
 * @CreateDate: 2024/6/6
 * @UpdateUser: wangjc
 * @UpdateDate: 2024/6/6
 * @UpdateRemark: 更新内容
 * @Version: 1.0
 */
@Slf4j
@Component
public class DingTalkUserAPI {

	/**
	 * 根据授权码获取用户信息。 该方法通过钉钉开放平台的接口，使用授权码来获取用户的基本信息。 主要用于在钉钉应用中进行用户身份的验证和信息获取。
	 *
	 * @param code 钉钉授权码，用于换取用户信息。
	 * @throws ApiException 如果接口调用失败，会抛出ApiException。
	 */
	public OapiV2UserGetuserinfoResponse.UserGetByCodeResponse getUserInfoByAuthCode(String code, String accessToken) throws ApiException {
		// 创建请求对象，并设置授权码
		OapiV2UserGetuserinfoRequest req = new OapiV2UserGetuserinfoRequest();
		req.setCode(code);
		// 执行请求，获取响应
		OapiV2UserGetuserinfoResponse rsp = IDingTalkClient.execute(OpenApiUrls.GET_USER_INFO_BY_CODE, req,
				accessToken);
		// 打印响应体，通常包含用户信息的JSON数据
		log.debug("钉钉开放平台接口响应体：{}", JSON.toJSONString(rsp.getBody()));
		return rsp.getResult();
	}

	/**
	 * 根据用户ID从钉钉接口获取用户信息。
	 *
	 * @param userId 钉钉用户ID
	 * @return 用户信息对象，如果获取失败则返回null
	 */
	public OapiV2UserGetResponse.UserGetResponse getUserInfoById(String userId, String accessToken) throws ApiException {
		// 创建钉钉API客户端
		// 创建获取用户信息的请求对象，并设置用户ID和语言
		OapiV2UserGetRequest req = new OapiV2UserGetRequest();
		req.setUserid(userId);
		req.setLanguage("zh_CN");
		// 执行请求，并传入访问令牌，访问令牌通过钉钉授权API获取
		OapiV2UserGetResponse rsp = IDingTalkClient.execute(OpenApiUrls.GET_USER_INFO_BY_ID, req, accessToken);
		// 记录用户信息到日志
		log.debug("钉钉开放平台接口响应体：{}", JSON.toJSONString(rsp.getBody()));
		return rsp.getResult();
	}

	/**
	 * 根据部门ID查询钉钉用户ID列表。 该方法通过调用钉钉接口来实现，首先构造请求，然后发送请求并获取响应。
	 * 目前该方法实现了查询功能但未对结果进行处理，返回值暂设为null。
	 *
	 * @param req ListUserVO对象，包含部门ID等信息，用于构建请求参数。
	 * @return 返回null，未来可能根据实际需要修改为返回用户ID列表。
	 */
	public OapiUserListidResponse.ListUserByDeptResponse listUserIdByDeptId(OapiUserListidRequest req,
		String accessToken) throws ApiException {
		// 创建请求对象，并设置部门ID
		// 执行请求，并获取响应
		OapiUserListidResponse rsp = IDingTalkClient.execute(OpenApiUrls.LIST_USER_ID, req, accessToken);
		// 打印响应体，用于调试和日志记录
		log.debug("钉钉开放平台接口响应体：{}", JSON.toJSONString(rsp.getBody()));
		return rsp.getResult();
	}

	/**
	 * 根据部门ID查询用户列表
	 *
	 * @param req 查询请求对象，包含部门ID等信息
	 * @return 用户列表的响应结果
	 */
	public OapiV2UserListResponse.PageResult listUserByDeptId(OapiV2UserListRequest req, String accessToken) throws ApiException {
		// 设置查询参数，按修改时间降序排列，语言为中文
		req.setOrderField("modify_desc");
		req.setLanguage("zh_CN");

		// 调用钉钉接口查询用户列表
		OapiV2UserListResponse rsp = IDingTalkClient.execute(OpenApiUrls.LIST_USER, req, accessToken);

		// 打印响应体，用于调试和日志记录
		log.debug("钉钉开放平台接口响应体：{}", JSON.toJSONString(rsp.getBody()));

		// 返回查询结果
		return rsp.getResult();
	}
}
